package com.example.web;

import com.example.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.cluster.lock.DistributedLock;
import org.springframework.cloud.cluster.lock.support.DelegatingDistributedLock;
import org.springframework.cloud.cluster.redis.lock.RedisLockService;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Set;
import java.util.concurrent.locks.Lock;

import static com.sun.org.apache.xerces.internal.util.FeatureState.is;

/**
 * Created by Administrator on 2017/3/2 0002.
 */
@RestController
@RequestMapping("/redis")
public class RedisController {

//    @Autowired
//    private RedisService redisService;

//    @RequestMapping("/set")
//    public Object redisSet(@RequestParam("value")String value){
//        boolean isOk = redisService.set("name", value);
//        return isOk;
//    }
//
//    @RequestMapping("/get")
//    public Object redisGet(){
//        String name = redisService.get("name");
//        return name;
//    }

    @Autowired
    private RedisTemplate<String, User> redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisConnectionFactory connectionFactory;

    @RequestMapping("/test")
    public Object test() throws Exception {
        // 保存对象
        User user = new User("超人", 20);
        redisTemplate.opsForValue().set(user.getUsername(), user);
        user = new User("蝙蝠侠", 30);
        redisTemplate.opsForValue().set(user.getUsername(), user);
        user = new User("蜘蛛侠", 40);
        redisTemplate.opsForValue().set(user.getUsername(), user);
        System.out.println(redisTemplate.opsForValue().get("超人").getAge().longValue());
        System.out.println(redisTemplate.opsForValue().get("蝙蝠侠").getAge().longValue());
        System.out.println(redisTemplate.opsForValue().get("蜘蛛侠").getAge().longValue());
        stringRedisTemplate.opsForValue().set("aaa", "111");
        System.out.println(stringRedisTemplate.opsForValue().get("aaa"));
        return redisTemplate.opsForValue().get("超人");
    }

    @RequestMapping("/testlock")
    public Object testlock() {
        RedisLockService lockService = new RedisLockService(connectionFactory);
        Lock lock = lockService.obtain("lock");
        try {
            lock.lock();
            User user = new User("煎饼侠", 32);
            redisTemplate.opsForValue().set(user.getUsername(), user);
        } finally {
            lock.unlock();
        }
        return null;
    }

    @RequestMapping("/testlock2")
    public Object testlock2() {
        RedisLockService lockService = new RedisLockService(connectionFactory);
        DelegatingDistributedLock lock = (DelegatingDistributedLock) lockService.obtain("lock");
        try {
            lock.lock();
            User user = new User("煎饼侠2", 35);
            redisTemplate.opsForValue().set(user.getUsername(), user);
        } finally {
            lock.unlock();
        }
        return null;
    }

    /**
     * 加上锁后，另一个试图获取锁
     * @return
     */
    @RequestMapping("/testlock3")
    public Object testlock3() {
        RedisLockService lockService = new RedisLockService(connectionFactory);
        DistributedLock lock1 = lockService.obtain("lock");
        DistributedLock lock2 = lockService.obtain("lock");
        lock1.lock();
        // same thread so try/lock doesn't fail
        boolean b = lock2.tryLock();
        if (b) {
            System.out.println(true);
        }
        lock2.lock();

        Set<String> keys = redisTemplate.keys(RedisLockService.DEFAULT_REGISTRY_KEY + ":*");
        int size = keys.size();
        if (size==1) {
            System.out.println(size);
        }
        String next = keys.iterator().next();
        if (next.equals(RedisLockService.DEFAULT_REGISTRY_KEY + ":lock")) {
            System.out.println(RedisLockService.DEFAULT_REGISTRY_KEY + ":lock");
        }

        lock1.unlock();
        lock2.unlock();
        return null;
    }

}
